"use strict";
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EntityPool = exports.EcsEntity = void 0;
var EcsComponent_1 = require("./EcsComponent");
var EcsEntity = /** @class */ (function () {
    function EcsEntity(factory) {
        this.id = 0;
        this.groupId = "";
        this.componentMap = new Map();
        this.enabledComponentMap = new Map();
        this.__valid = false;
        this._factory = null;
        this._factory = factory;
    }
    /**
     * 通过组件id列表获取分组id
     * @param compIds
     * @returns
     */
    EcsEntity.getGroupID = function (compIds) {
        //const sorted= compIds.slice().sort((a, b) => { return a - b })
        var result = 0;
        for (var i = 0; i < compIds.length; i++) {
            result += Math.pow(2, compIds[i]);
        }
        return result.toString();
        // return sorted.join(",");
    };
    EcsEntity.prototype.recover = function () {
        // for (let i = 0; i < this.__comps.length; i++) {
        // 	if (this.__comps[i]) {
        // 		this.__comps[i].enable = false;
        // 	}
        // }
        this._factory.recover(this);
    };
    EcsEntity.prototype.destroy = function () {
        //TODO
        return true;
    };
    Object.defineProperty(EcsEntity.prototype, "valid", {
        get: function () {
            return this.__valid;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(EcsEntity.prototype, "componentsID", {
        get: function () {
            return this.groupId;
        },
        enumerable: false,
        configurable: true
    });
    EcsEntity.prototype.component = function (compClz) {
        return this.componentMap.get(compClz.__compId);
    };
    EcsEntity.prototype.hasAllCompIds = function () {
        var compIds = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            compIds[_i] = arguments[_i];
        }
        for (var i = 0; i < compIds.length; i++) {
            if (!this.componentMap.get(compIds[i])) {
                return false;
            }
        }
        return true;
    };
    return EcsEntity;
}());
exports.EcsEntity = EcsEntity;
var EntityPool = /** @class */ (function () {
    function EntityPool(components) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        this.compIds = [];
        this._compDefs = [];
        this.groupId = "";
        this._pool = [];
        this.defineComps.apply(this, __spreadArray([components], args, false));
    }
    /**定义组件 */
    EntityPool.prototype.defineComp = function (componentClz) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        var componentId = EcsComponent_1.EcsComponent.getIdFromClz(componentClz);
        this.compIds.push(componentId);
        this._compDefs.push({ id: componentId, type: componentClz, args: args });
        return this;
    };
    /**定义组件 */
    EntityPool.prototype.defineComps = function (components) {
        var _this = this;
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        components.forEach(function (element) {
            _this.defineComp(element, args);
        });
        this.groupId = EcsEntity.getGroupID(this.compIds);
        return this;
    };
    EntityPool.resetComp = function (comp, cst) {
        cst.instance;
        var instance = cst.instance();
        Object.assign(comp, instance);
        if (cst.__objPropKeys) {
            cst.__objPropKeys.forEach(function (key) {
                comp[key] = JSON.parse(JSON.stringify(instance[key]));
            });
        }
    };
    EntityPool.prototype.create = function (entityId) {
        var _a;
        var _obj = this._pool.length > 0 ? this._pool.pop() : null;
        if (_obj == null) { //对象池中没有
            _obj = new EcsEntity(this);
            for (var i = 0; i < this._compDefs.length; i++) {
                var _def = this._compDefs[i];
                var _comp = new ((_a = _def.type).bind.apply(_a, __spreadArray([void 0], _def.args, false)))();
                _obj.componentMap.set(_def.id, _comp);
            }
        }
        else { //从对象池直接获取的
            for (var i = 0; i < this._compDefs.length; i++) {
                var _def = this._compDefs[i];
                var _comp = _obj.componentMap.get(_def.id);
                EcsComponent_1.EcsComponent.resetComp(_comp, _def.type);
            }
        }
        _obj.id = entityId;
        _obj.groupId = this.groupId;
        for (var i = 0; i < this._compDefs.length; i++) {
            var _def = this._compDefs[i];
            _obj.componentMap.get(_def.id).__ownerId = _obj.id;
        }
        _obj.__valid = true;
        return _obj;
    };
    EntityPool.prototype.recover = function (entity) {
        entity.id = 0;
        entity.__valid = false;
        this._pool.push(entity);
    };
    return EntityPool;
}());
exports.EntityPool = EntityPool;
